package com.sky.aspect;

import com.sky.context.BaseContext;
import com.sky.utils.HttpContextUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.Enumeration;

@Slf4j
@Aspect
@Component
public class LoggingAspect {

    /**
     * 定义切入点，匹配所有 Controller 层的公共接口
     */
    @Pointcut("execution(* com.sky.controller..*(..))")
    public void controllerPointcut() {
    }

    /**
     * 环绕通知，用于记录接口访问日志和监控执行时间
     */
    @Around("controllerPointcut()")
    public Object logAndMonitor(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

        // 获取请求的相关信息（如需要从上下文获取）
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        String requestURI = request.getRequestURI();
        String httpMethod = request.getMethod();

        // 打印请求信息
        log.info("请求开始: URI={}, 方法={}, 参数={}, 用户id={}", requestURI, httpMethod, getRequestParams(request), BaseContext.getCurrentId());

        // 执行目标方法
        Object result;
        try {
            result = joinPoint.proceed();
        }finally {
            long executionTime = System.currentTimeMillis() - startTime;
            log.info("请求结束: URI={}, 执行时间={}ms", requestURI, executionTime);
        }
        return result;
    }

    /**
     * 获取请求参数
     */
    private String getRequestParams(HttpServletRequest request) {
        StringBuilder params = new StringBuilder();
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String paramName = parameterNames.nextElement();
            params.append(paramName).append("=").append(request.getParameter(paramName)).append("&");
        }
        return params.length() > 0 ? params.substring(0, params.length() - 1) : "无参数";
    }
}